// let arr = [1, 2, 3]
// let a = arr[0]
// let b = arr[1]
// let c = arr[2]
// let [a, b, c] = [1, 2, 3]
// console.log(a, b, c)

// let [a, b, [c, d]] = [1, 2, [3, 4]]
// console.log(a, b, c, d)

// let [a, b, [c]] = [1, 2, [3, 4]]
// console.log(a, b, c)

// let [a, b, c] = [1, 2, [3, 4]]
// console.log(a, b, c)

// let [a, b, c, d = 5] = [1, 2, [3, 4], 6]
// console.log(a, b, c, d)

// let user = {
//     name: 'xiecheng',
//     age: 34
// }
// // let name = user.name
// // let age = user.age
// let {age: uage, name: uname} = user

// console.log(uname, uage)

// let str = 'imooc'
// // for (let i = 0; i < str.length; i++) {
// //     console.log(str[i])
// // }
// let [a, b, c, d, e] = str
// console.log(a, b, c, d, e)

// let [a, b, c = 8] = [4, 5, 6]
// console.log(a, b, c)

// let {name, age = 18} = {
//     name: 'xiecheng',
//     // age: 34
// }
// console.log(name, age)

// function foo(){
//     console.log(123)
// }
// let [a = foo()] = []

// function foo([a, b, c]) {
//     console.log(a, b, c)
// }
// let arr = [1, 2, 3]
// foo(arr)

// function foo({name, age, school = 'imooc'}) {
//     console.log(name, age, school)
// }
// let obj = {
//     name: 'xiecheng',
//     age: 34,
//     school: 'xxx'
// }
// foo(obj)

// function foo() {
//     let obj = {
//         name: 'xiecheng',
//         age: 34,
//         school: 'xxx'
//     }
//     return obj
// }
// let {name, age} = foo()
// console.log(name, age)

// json
// let json = '{"a": "hello", "b": "world"}'
// let {a, b}= JSON.parse(json)
// console.log(a, b)

// var a = 1;
// function fn1(){
//     alert(a);
//     var a = 2;
// }
// fn1();
// alert(a);

// String.prototype.repeatify = String.prototype.repeatify || function(times) {
//     var str = '';
//     for (var i = 0; i < times; i++) {
//         console.log(this)
//         str += this;
//     }
//     return str;
// };
// console.log('hello'.repeatify(3))

//
// 输出结果 1 2 4 3  promise构造函数是同步执行的，promise.then 中的函数是异步执行的

// const promise1 = new Promise((resolve,reject)=>{
//     setTimeout(()=>{
//         resolve('success')
//     },1000)
// })
// const promise2 = promise1.then(()=>{
//     throw new Error('error!!!')
// })
//
// console.log('promise1',promise1)
// console.log('promise2',promise2)
//
// setTimeout(()=>{
//     console.log('promise1',promise1)
//     console.log('promise2',promise2)
// },2000)

// const promise = new Promise((resolve, reject) => {
//     setTimeout(()=>{
//         console.log('once')
//         resolve('success')
//     },1000)
// })
//
// const start = Date.now()
// promise.then(res=>{
//     console.log(res,Date.now()-start)
// })
// promise.then(res=>{
//     console.log(res,Date.now()-start)
// })

// Promise.resolve()
//     .then(()=>{
//         return new Error('error!!!')
//     })
//     .then((res)=>{
//         console.log('then:',res)
//     })
//     .catch(err=>{
//         console.log('catch',err)
//     })
// // 返回结果 then: Error: error!!!  因.then或者.catch 中return一个error对象并不会抛出错误，所以不会被后续的.catch捕获
//
// Promise.reject(new Error('error!!!'))
//     .then((res)=>{
//         console.log('then:',res)
//     })
//     .catch(err=>{
//         console.log('catch',err)
//     })

// Promise.resolve(1)
//     .then(2)
//     .then(Promise.resolve(3))
//     .then(console.log)

// Promise.resolve()
//     .then(res=>{
//         throw new Error('error')
//     },err=>{
//         console.error('fail1:',err)
//     })
//     .catch(err=>{
//         console.error('fail2:',err)
//     })

// var p1 = new Promise( function(resolve,reject){
//     foo.bar();
//     resolve( 1 );
// });
//
// p1.then(
//     function(value){
//         console.log('p1 then value: ' + value);
//     },
//     function(err){
//         console.log('p1 then err: ' + err);
//     }
// ).then(
//     function(value){
//         console.log('p1 then then value: '+value);
//     },
//     function(err){
//         console.log('p1 then then err: ' + err);
//     }
// );
//
// var p2 = new Promise(function(resolve,reject){
//     resolve( 2 );
// });
//
// p2.then(
//     function(value){
//         console.log('p2 then value: ' + value);
//         foo.bar();
//     },
//     function(err){
//         console.log('p2 then err: ' + err);
//     }
// ).then(
//     function(value){
//         console.log('p2 then then value: ' + value);
//     },
//     function(err){
//         console.log('p2 then then err: ' + err);
//         return 1;
//     }
// ).then(
//     function(value){
//         console.log('p2 then then then value: ' + value);
//     },
//     function(err){
//         console.log('p2 then then then err: ' + err);
//     }
// );

// let p1 = Promise.resolve(1)
// let p2 = Promise.resolve(p1)
// let p3 = new Promise((resolve, reject) => {
//     resolve(1)
// })
// let p4 = new Promise((resolve, reject) => {
//     resolve(p1)
// })
//
// console.log(p1 === p2)
// console.log(p1 === p3)
// console.log(p1 === p4)
// console.log(p3 === p4)
//
// p4.then(value => {
//     console.log('p4=' + value)
// })
//
// p2.then(value => {
//     console.log('p2=' + value)
// })
//
// p1.then(value => {
//     console.log('p1=' + value)
// })
//
// let p1 = new Promise((resolve, reject) => {
//     resolve(Promise.resolve('resolve'))
// })
//
// let p2 = new Promise((resolve, reject) => {
//     resolve(Promise.reject('reject'))
// })
//
// let p3 = new Promise((resolve, reject) => {
//     reject(Promise.resolve('resolve'))
// })
//
// p1.then(
//     res => {
//         console.log('fulfilled:' + res)
//     },
//     rej => {
//         console.log('rejected:' + rej)
//     })
//
// p2.then(
//     res => {
//         console.log('fulfilled:' + res)
//     },
//     rej => {
//         console.log('rejected:' + rej)
//     }
// )
//
// p3.then(
//     res => {
//         console.log('fulfilled:' + res)
//     },
//     rej => {
//         console.log('rejected:' + rej)
//     }
// )

// console.log(Object.prototype.toString.call(()=>{}))
// console.log(Object.prototype.toString.call(()=>{}).indexOf('Function'))
// console.log(typeof(null))
// console.log(Array.isArray([1,2]))
// let symTest = Symbol('test')
// console.log(typeof symTest)

// function f() {
//     let num = 3
//     return function () {
//         let n = 0
//         console.log(++n)
//         console.log(++num)
//     }
// }
// let fn1 = f()
// fn1()
// fn1()

// var n=10;
// var num = n++ //++在后
// var result=++n  //++在前
// console.log("num为"+num,"n的值为:"+n);
// console.log("result为"+result,"n的值为:"+n);

// for (var i = 0; i < 3; i++) {
//     setTimeout(() => {
//         console.log(i)
//     }, 100)
// }
//
// for (let i = 0; i < 3; i++) {
//     setTimeout(() => {
//         console.log(i)
//     }, 100)
// }
//
// for (var i = 0; i < 3; i++) {
//     (function (i) {
//         setTimeout(() => {
//             console.log(i)
//         }, 100)
//     })(i)
// }

// let arr1 = [1,2,3]
// let arr2 = arr1
// console.log(arr2)
// arr1.shift()
// console.log(arr1)
// console.log(arr2)

//深拷贝
// JSON.parse(JSON.stringify())

// 定义一个深拷贝函数  接收目标target参数
function deepClone(target) {
    // 定义一个变量
    let result;
    // 如果当前需要深拷贝的是一个对象的话
    if (typeof target === 'object') {
        // 如果是一个数组的话
        if (Array.isArray(target)) {
            result = []; // 将result赋值为一个数组，并且执行遍历
            for (let i in target) {
                // 递归克隆数组中的每一项
                result.push(deepClone(target[i]))
            }
            // 判断如果当前的值是null的话；直接赋值为null
        } else if (target === null) {
            result = null;
            // 判断如果当前的值是一个RegExp对象的话，直接赋值
        } else if (target.constructor === RegExp) {
            result = target;
        } else {
            // 否则是普通对象，直接for in循环，递归赋值对象的所有值
            result = {};
            for (let i in target) {
                result[i] = deepClone(target[i]);
            }
        }
        // 如果不是对象的话，就是基本数据类型，那么直接赋值
    } else {
        result = target;
    }
    // 返回最终结果
    return result;
}

// let a = {
//     name: 'sl',
//     age: 26
// }
// let b = deepClone(a)
// console.log(b)
// a.name='hh'
// console.log(b)
//
// let c = a
// console.log(c)

// let a = [1, 2, 3, [4, 5]]
// let b = deepClone2(a)
// console.log(b)

// let a = {
//     name: 'sl',
//     age: 26,
//     senName:Symbol('aa')
// }
// let b = deepClone2(a)
// console.log(b)

// 数组去重
let arr = [1, 2, 3, 4, 5, 1, '1']
// let arr2 = [...new Set(arr)]
// console.log(arr2)
// let arr2 = Array.from(new Set(arr))
// console.log(arr2)
// let arr2 = arr.reduce((ar,cur)=>{
//     if (!ar.includes(cur)){
//         ar.push(cur)
//     }
//     return ar
// },[])
// console.log(arr2)
// 这种方法会有一个问题，[1，‘1’]会被当做不相同元素
// let arr2 = arr.filter((item,index)=>{
//     return arr.indexOf(item) === index
// })
// console.log(arr2)
// function unique1(arr) {
//     let newArr = []
//     for (let item of arr) {
//         if (newArr.indexOf(Number(item)) == -1)
//             newArr.push(item)
//     }
//     return newArr
// }
//
// console.log(unique1(arr))
// function uniqueEasy(arr) {
//     if (!Array.isArray(arr)) return
//     let obj = {}
//     let list = []
//     arr.forEach((item)=>{
//         if (!obj[item]){
//             list.push(item)
//             obj[item]=true
//         }
//     })
//     return list
// }
// console.log(uniqueEasy(arr))

// function add(num1, num2) {
//     let num  = num1 + num2
//     if (num2 + 1 > 100) {
//         return num
//     } else {
//         return add(num,num2 + 1)
//     }
// }
//
// let sum = add(1, 2)
// console.log(sum)

//创建XMLHttpRequest()
// var xhr
// if (window.XMLHttpRequest){
//     xhr = window.XMLHttpRequest
// }else if(window.ActiveXObject){
//     xhr = window.ActiveXObject
// }
// xhr.open('GET','http://www.example.com',true)
// xhr.setRequestHeader('Content-Type','application/x-www-from-urlencoded')
// xhr.onreadystatechange=()=>{
//     if (xhr.readyState===4&&xhr.status===200){
//         let res = xhr.responseText
//     }
// }
// xhr.send()

// function PublicFun(name,age) {
//     this.name = name
//     this.age = age
// }
//
// PublicFun.prototype.getName = function(){
//     console.log(this.name)
// }
//
// const text1 = new PublicFun('师林','26')
// text1.getName()
//
// class PublicFun{
//     constructor(name,age){
//         this.name=name
//         this.age=age
//     }
//     getName(){
//         console.log(this.name)
//     }
// }
// let text = new PublicFun('师林','26')
// text.getName()

// function PublicFun(name,age) {
//     this.name = name
//     this.age = age
// }
// PublicFun.prototype.getName = function () {
//     console.log(this.name)
// }
// let p = new PublicFun('师林','26')
//
// function PublicFun1(name,age,sex) {
//     PublicFun.call(this,name,age)
//     this.sex = sex
// }
// PublicFun1.prototype = Object.create(PublicFun.prototype)
// PublicFun1.prototype.getAllMess = function () {
//     console.log(this.name,this.age,this.sex)
// }
// let p1 = new PublicFun1('师林','26','男')
// p1.getName()
// p1.getAllMess()

const obj = {
    name: '师林',
    age: '15',
    mess: {
        a: '1',
        b: '2'
    }
}

// function deepFreeze(obj) {
//     let loopObj
//     Object.freeze(obj)
//     for (let key in obj) {
//         loopObj = obj[key]
//         if (!typeof loopObj === 'object' || !obj.hasOwnProperty(key) || Object.isFrozen(loopObj)){
//             continue
//         }
//         deepFreeze(loopObj)
//     }
// }
// function deepFreeze(obj){
//     let loopDeep
//     Object.freeze(obj)
//     for (let key in obj){
//         loopDeep = obj[key]
//         if (!obj.hasOwnProperty(key)||Object.isFrozen(loopDeep)||!typeof loopDeep==='object'){
//             continue
//         }
//         deepFreeze(loopDeep)
//     }
// }
// obj.mess.a='123'
// console.log(obj)
// deepFreeze(obj)
// obj.mess.a='456'
// console.log(obj)

// function Dog(name) {
//     this.name = name;
//     this.speak = function() {
//         return 'woof';
//     };
// }
//
// const dog = new Dog('Pogo');
//
// Dog.prototype.speak = function() {
//     return 'arf';
// };
//
// console.log(dog.speak());

// const timer = a => {
//     return new Promise(res =>
//         setTimeout(() => {
//             res(a);
//         }, Math.random() * 100)
//     );
// };
//
// const all = Promise.all([timer('first'), timer('second')]).then(data =>
//     console.log(data)
// );

// const arr2 = [x => x * 1, x => x * 2, x => x * 3, x => x * 4];
//
// console.log(arr2.reduce((agg, el) => agg + el(agg), 1));

//短路通知
// const notifications = 1;
//
// console.log(
//     `You have ${notifications} notification${notifications !== 1 && 's'}`
// );




